package com.fjwt.gz.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fjwt.gz.components.mq.model.ExportExcelMQ;
import com.fjwt.gz.components.mq.vender.IMQSender;
import com.fjwt.gz.core.constants.Constants;
import com.fjwt.gz.core.entity.SysUser;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.db.dto.StatScoreRecordDTO;
import com.fjwt.gz.db.entity.StatScoreRecordEntity;
import com.fjwt.gz.db.vo.ScoreRecordTotalVO;
import com.fjwt.gz.db.vo.StatScoreNumDayVO;
import com.fjwt.gz.db.vo.StatScoreNumMonthVO;
import com.fjwt.gz.db.vo.StatScoreRecordVO;
import com.fjwt.gz.service.mapper.StatScoreRecordMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 统计：会员积分动作表 服务实现类
 * </p>
 *
 * @author shiyonghao
 * @since 2025-07-24
 */
@Slf4j
@Service
public class StatScoreRecordService extends ServiceImpl<StatScoreRecordMapper, StatScoreRecordEntity> {

    @Autowired
    private ScoreRecordTotalService scoreRecordTotalService;
    @Autowired
    private SysExportTaskService sysExportTaskService;
    @Autowired
    private IMQSender mqSender;

    /**
     * 获取统计数据
     */
    public IPage selectDailyScoreRecords(IPage<StatScoreRecordEntity> iPage, StatScoreRecordDTO scoreRecordDTO) {
        return baseMapper.selectPage(iPage, StatScoreRecordEntity.gw()
                .eq(scoreRecordDTO.getFansId() != null, StatScoreRecordEntity::getFansId, scoreRecordDTO.getFansId())
                .eq(StrUtil.isNotBlank(scoreRecordDTO.getPhone()), StatScoreRecordEntity::getPhone, scoreRecordDTO.getPhone()));
    }

    /**
     * 获取导出数据
     */
    public List<StatScoreRecordVO> selectExportScoreRecords(StatScoreRecordDTO scoreRecordDTO) {
        return baseMapper.selectExportScoreRecords(scoreRecordDTO);
    }

    @Transactional(rollbackFor = Exception.class)
    public void generateDailyStatistics(DateTime date) {
        String time = DateUtil.format(date, "yyyy-MM-dd");

        // 2. 查询源数据
        List<ScoreRecordTotalVO> records = scoreRecordTotalService.selectDailyScoreRecords(time);
        if (records.isEmpty()) {
            return;
        }

        // 3. 转换数据格式
        List<StatScoreRecordEntity> statisticsList = convertToStatistics(records);

        // 4. 批量插入统计表
        saveBatchStatistics(statisticsList);
    }

    private List<StatScoreRecordEntity> convertToStatistics(List<ScoreRecordTotalVO> records) {
        List<StatScoreRecordEntity> result = new ArrayList<>();

        for (ScoreRecordTotalVO record : records) {
            StatScoreRecordEntity stat = new StatScoreRecordEntity();

            // 直接映射字段
            stat.setFansId(record.getFansId())
                    .setPhone(record.getPhone())
                    .setLiteAppId(record.getAppId())
                    .setAgentScoreId(record.getAgentScoreId())
                    .setChangeCause(record.getName())
                    .setChangeScore(record.getScore())
                    .setChangeTime(record.getCreatedAt())
                    .setAgentNo4(record.getAgentNo4())
                    .setAgentName4(record.getAgentName4())
                    .setAgentNo3(record.getAgentNo3())
                    .setAgentName3(record.getAgentName3())
                    .setAgentNo2(record.getAgentNo2())
                    .setAgentName2(record.getAgentName2())
                    .setAgentNo1(record.getAgentNo1())
                    .setAgentName1(record.getAgentName1());

            // 转换字段
            Integer flag = record.getFlag();
            stat.setChangeType(flag == 0 ? "ADD" : flag == 1 ? "USED" : "OVER_TIME");

            String infoType = record.getInfoType();
            if ("COUPON".equals(infoType)) {
                stat.setTag("EXCHANGE_COUPON");
            }
            if ("RULE".equals(infoType) || "ASSET_MONTH".equals(infoType) || "CARD_MONTH".equals(infoType)) {
                stat.setTag("BAI_FU_JIN_MEN");
            }

            result.add(stat);
        }

        return result;
    }

    private void saveBatchStatistics(List<StatScoreRecordEntity> list) {
        // 使用Mybatis-Plus批量插入
        int batchSize = 1000;
        int total = list.size();

        for (int i = 0; i < total; i += batchSize) {
            int end = Math.min(i + batchSize, total);
            List<StatScoreRecordEntity> subList = list.subList(i, end);
            baseMapper.insert(subList);
        }
    }


    public void export(StatScoreRecordDTO scoreRecordDTO, SysUser sysUser) {
        List<StatScoreRecordEntity> list = baseMapper.selectList(StatScoreRecordEntity.gw());
        if (CollUtil.isEmpty(list)) {
            log.info("没有数据");
            throw new BizException("无数据可导出");
        }
        //导出上个月的数据
        String time = DateUtil.format(DateUtil.lastMonth(), "yyyyMM");
        scoreRecordDTO.setStatTime(time);
        String fileName = time + "福分记录明细数据报表";
        // 添加导出任务记录
        Long exportTaskId = sysExportTaskService.addExportTask(sysUser, fileName, Constants.EXPORT_TASK_ENUM.REQUEST_CODE.SCORE_RECORD,
                Constants.EXPORT_TASK_ENUM.RESOURCE_TYPE.FANS, JSONObject.toJSONString(scoreRecordDTO));
        // 发送mq
        mqSender.send(ExportExcelMQ.build(exportTaskId));

    }

    /**
     * 获取积分统计
     * @param type 统计时间类型 按月统计 按日统计
     * @param time 统计时间
     * @return
     */
    public List<StatScoreNumDayVO> getScoreNumDayOrMonthStatistics(String type, String time) {
        return baseMapper.getScoreNumDayOrMonthStatistics(type, time);
    }

    /**
     * 统计已迁移积分
     *
     * @param type 统计时间类型 按月统计 按日统计
     * @param time 统计时间
     * @return
     */
    public List<StatScoreNumDayVO> getSyncScoreNumDayOrMonthStatistics(String type, String time) {
        return baseMapper.getSyncScoreNumDayOrMonthStatistics(type, time);
    }

    /**
     * 获取上个月的核销积分统计
     *
     * @param time 统计时间月份
     * @return
     */
    public List<StatScoreNumMonthVO> getConsumeCouponYuan(String time) {
        return baseMapper.getConsumeCouponYuan(time);
    }
}
